DIY Exercise 8-1: Orchestrate web services
Time estimate: 3 hours
Objectives
In this exercise, you retrieve data from several different data sources and combine them using DataWeave. You will:
· Retrieve data from a REST service.
· Retrieve data from a SOAP service.
· Use DataWeave to transform and combine data from two sources into a new data structure.
· Upload data to an external REST service.
Scenario
The Finance department is using two APIs: Accounts and Transactions. Currently, their analysts have to retrieve information from both APIs separately and then combine them using a spreadsheet. The Finance department is requesting a Process API that can combine accounts information with transaction information to reduce the manual work needed to combine the data in a spreadsheet.
Your task is to implement this Process API. First, you need to create a new Mule application that retrieves account information using the Accounts System API and then uses the Transactions System API to retrieve transaction data for each account. Each account can have zero or more transactions. Next, you need to transfer these records to several different Finance directors using an existing Experience API. To do this, you need to join the transaction data for each account with the other account record details to create a new data structure compatible with the existing Experience API. The expected behavior of the new application is specified in the Transfer Accounts API: /files/module08/accounts-transactions-mod08-api.zip (in the MUFundamentals4.x DIY Files zip that you can download from the Course Resources).
Review the Accounts API
Review the Accounts API you created in exercise 3-1 or the solution /files/module03/accounts-mod03-api.zip (in the MUFundamentals4.x DIY Files zip that you can download from the Course Resources).
The Accounts API:
· Has an endpoint http://apdev-accounts-ws.cloudhub.io/api/accounts to request all accounts of a particular type (personal or business).
· Requires a query parameter named type set to personal or business.
· Requires a Requester-ID header.
· Has two other optional query parameters named country and name that can be used to filter the accounts to just a particular account owner's name or to the country of residence of the account holder.
· Returns a JSON array of matching Account objects.
Define a Process API to look up accounts and transfer transactions to the Finance directors reporting system
Define a Transfer Accounts API that accepts GET requests with the required Requester-ID and type query parameter (where type must be business or personal). This API is used to retrieve all accounts from the Accounts API for a particular Requester-ID and account type (business or personal) and then filtering them using the optional country and name query parameters. In the API definition, provide an example to show that the response should be a string indicating the number of messages processed.
Create a new application to retrieve data from the Accounts API
In Anypoint Studio, create a new Mule application that uses the Accounts API to retrieve accounts with the required and optional parameters specified in the Accounts API. The Mule application should accept the type, name, and country query parameters. Set the Requester-ID header to a static value.
Hint: You can use a Validator or a Choice router to test for required values. You can also set default values directly in DataWeave if a required parameter or header is null:
#[attributes.queryParams.type default "business"]
After checking for required attributes and parameters (and perhaps setting default values), add an HTTP Request to make the GET request to the Accounts API.
Hint: Remember to set the required Requestor-ID header and the required type query parameter.
Retrieve data from the transaction web service
After you have the array of JSON objects returned from the Accounts System API, pass a list of account IDs to the GetTransactionsforCustomers operation of the Transaction SOAP web service: http://apdev-accounts-ws.cloudhub.io/api/transactions?wsdl. The web service requires the request body to contain an XML request with a list of customerID values, where each customerID should correspond to one accountID returned from the Accounts System API:
<?xml version='1.0' encoding='UTF-8'?>
<ns0:GetTransactionsforCustomers xmlns:ns0="http://training.mulesoft.com/">
<customerID>4402</customerID>
<customerID>4404</customerID>
<customerID>4464</customerID>
</ns0:GetTransactionsforCustomers>
Hint: You can use the following DataWeave script to return an array of account IDs from the payload resulting from a call to the Accounts System API. The code default [] returns an array by default if payload.*id evaluates to null.
{customerIDs: payload.*id default []}
Make a request to the Mule application and verify matching transactions are returned from the SOAP query.
Here are a few example transactions results:
{
"amount": "9717.0",
"customerRef": "4412",
"flightID": "UNITEDER09452015-06-11",
"region": "EU",
"transactionID": "181948488"
},
{
"amount": "1030.0",
"customerRef": "4985",
"flightID": "DELTAA1B3D42015-02-12",
"region": "US",
"transactionID": "181948625"
}
Combine accounts and transactions data into a simple data structure
After retrieving data from accounts and transactions, combine them together in the simplest way:
{
"accounts": Array of Account Objects
"transactions": Array of all Transaction Objects for all accounts
}
Note: In the next step, you will create a more complex and normalized data structure.
Hint: A Transform Message component can create several different transformations at a time and output the results to variables. To add a new output target for the Transform Message component, click the plus icon to the left of the pencil icon in the Script Editor.
Join accounts and transaction data
Use the following DataWeave code to join the transaction details to each account in a hierarchical object structure. You can also find this code in the text file /files/module08/dwTransform.txt (in the MUFundamentals4.x DIY Files zip that you can download from the Course Resources).
%dw 2.0
output application/java
var directorIDs = ["JKLS483S","FJSA48JD","NMA4FJ9K"]
//Combines Accounts and Transactions by the Account ID. Assigns each account to a
//director
fun consolidateAccountsTrans (payload) =
payload.accounts map ( (account, index) ->
using (id = account.id as :string)
(
account ++
{
transactions: payload.transactions filter ($.customerRef == id)
} ++
{
assignedDirector: directorIDs[index mod sizeOf directorIDs]
}
)
)
---
using (data = consolidateAccountsTrans(payload))
(data groupBy $.assignedDirector)
Note: This DataWeave code creates the correct schema expected by the Experience API you will POST to in the next step.
Transfer enriched accounts data to corresponding Finance directors
An Experience API has been created that can be used to
transfer records to Finance directors. It is available by making a POST request
to:
http://apdev-accounts-ws.cloudhub.io/api/accounts_transactions
Note: This current implementation always returns the JSON response {"message": "Success"}. You do not need to set any headers or other parameters, and the body can be anything. This web service is slow and takes more than 10 seconds to return a response.
Return the number of records processed
Modify the Mule application to return a final payload with a message confirming the number of account records processed.
Note: Because the current Experience API does not return the number of processed records, just count the number of records sent in the outbound request to the Experience API.
Complete the transferAccounts API contract
Format the response to the request so that it conforms to the Transfer Accounts API you created.
Verify your solution
Import the solution /files/module08/accounts-transactions-mod08-joining-data-solution.jar deployable archive file into Anypoint Studio (in the MUFundamentals4.x DIY Files zip that you can download from the Course Resources) and compare your solution.